home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 3 / CD ACTUAL 3.iso / linux / system / bsvc-1.000 / bsvc-1 / bsvc-1.0.4 / src / SimHector / cpu / DataPath.cxx < prev    next >
Encoding:
C/C++ Source or Header  |  1995-07-26  |  5.4 KB  |  226 lines

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // DataPath.cxx - Data Path for the Hector 1600 CPU
  4. //
  5. // By: Bradford W. Mott
  6. // December 3,1993
  7. //
  8. ///////////////////////////////////////////////////////////////////////////////
  9.  
  10. #include "DataPath.hxx"
  11.  
  12. ///////////////////////////////////////////////////////////////////////////////
  13. // The Constructor
  14. ///////////////////////////////////////////////////////////////////////////////
  15. DataPath::DataPath(BasicCPU* c)
  16.     : cpu(c)
  17. {
  18.   ResetSignals();
  19. }
  20.  
  21. ///////////////////////////////////////////////////////////////////////////////
  22. // The Destructor
  23. ///////////////////////////////////////////////////////////////////////////////
  24. DataPath::~DataPath()
  25. {
  26. }
  27.  
  28. ///////////////////////////////////////////////////////////////////////////////
  29. // Reset the data path signals
  30. ///////////////////////////////////////////////////////////////////////////////
  31. void DataPath::ResetSignals()
  32. {
  33.   // Reset all of the data path signals used for each clock cycle
  34.   MAR_SEL = MDR_SEL = NONE;
  35.   ALU_FN = DO_NOTHING;
  36.   MDR_LATCH = MAR_LATCH = IR_LATCH = 0;
  37.   MAR_OUT_EN = MDR_OUT_EN = 0;
  38.   A_SEL = B_SEL = -1;
  39.   WRT_A = WRT_B = DB_GT = ALU_GT = 0;
  40. }
  41.  
  42. void DataPath::a_sel(int reg)
  43. { A_SEL=reg; }
  44.  
  45. void DataPath::b_sel(int reg)
  46. { B_SEL=reg; }
  47.  
  48. void DataPath::wrt_a()
  49. { WRT_A=1; }
  50.  
  51. void DataPath::wrt_b()
  52. { WRT_B=1; }
  53.  
  54. void DataPath::db_gt()
  55. { DB_GT=1; }
  56.  
  57. void DataPath::alu_gt()
  58. { ALU_GT=1; }
  59.  
  60. void DataPath::alu_fn(ALUFunction function)
  61. { ALU_FN=function; }
  62.  
  63. void DataPath::mdr_sel(DataPathBus bus)
  64. { MDR_SEL=bus; }
  65.  
  66. void DataPath::mdr_latch()
  67. { MDR_LATCH=1; }
  68.  
  69. void DataPath::mdr_out_en()
  70. { MDR_OUT_EN=1; }
  71.  
  72. void DataPath::mar_sel(DataPathBus bus)
  73. { MAR_SEL=bus; }
  74.  
  75. void DataPath::mar_latch()
  76. { MAR_LATCH=1; }
  77.  
  78. void DataPath::mar_out_en()
  79. { MAR_OUT_EN=1; }
  80.  
  81. void DataPath::ir_latch()
  82. { IR_LATCH=1; }
  83.  
  84.  
  85. ///////////////////////////////////////////////////////////////////////////////
  86. // Read a word from memory
  87. ///////////////////////////////////////////////////////////////////////////////
  88. int DataPath::Peek(unsigned long address, unsigned int& value)
  89. {
  90.   unsigned char b1,b2;
  91.   address *= cpu->Granularity();
  92.  
  93.   if(!cpu->address_space[0].Peek(address,b1))
  94.     return(0);
  95.  
  96.   if(!cpu->address_space[0].Peek(address+1,b2))
  97.     return(0);
  98.  
  99.   value=((unsigned long)b1 << 8) | (unsigned long)b2;
  100.  
  101.   return(1);
  102. }
  103.  
  104. ///////////////////////////////////////////////////////////////////////////////
  105. // Write a word to memory
  106. ///////////////////////////////////////////////////////////////////////////////
  107. int DataPath::Poke(unsigned long address, unsigned int value)
  108. {
  109.   unsigned char b1,b2;
  110.   address *= cpu->Granularity();
  111.  
  112.   b1=value >> 8;
  113.   b2=value;
  114.  
  115.   if(!cpu->address_space[0].Poke(address,b1))
  116.     return(0);
  117.  
  118.   if(!cpu->address_space[0].Poke(address+1,b2))
  119.     return(0);
  120.  
  121.   return(1);
  122. }
  123.  
  124.  
  125.  
  126. ///////////////////////////////////////////////////////////////////////////////
  127. // Called at the end of each cycle to perform the actual cycle operations
  128. ///////////////////////////////////////////////////////////////////////////////
  129. const char* DataPath::Clock()
  130. {
  131.    // Put the selected registers onto the A & B Bus
  132.    if(A_SEL >= 0)
  133.       a_bus = register_set.GetRegister(A_SEL);
  134.    if(B_SEL >= 0)
  135.       b_bus = register_set.GetRegister(B_SEL);
  136.  
  137.    // Do the ALU Function
  138.    if(ALU_FN != DO_NOTHING)
  139.       alu_bus = alu.Compute(ALU_FN, a_bus, b_bus);
  140.  
  141.    // If mar_latch is set, put the appropriate bus contents into MAR
  142.    if(MAR_LATCH) {
  143.       switch (MAR_SEL) {
  144.          case A_BUS:
  145.             mar = a_bus;
  146.             break;
  147.          case B_BUS:
  148.             mar = b_bus;
  149.             break;
  150.          case ALU_BUS:
  151.             mar = alu_bus;
  152.             break;
  153.          default:    // mar_latch was set but mar_sel wasn't called
  154.             return("Simulator Logic Error: No mar_sel");
  155.       }
  156.    }
  157.  
  158.    // If mdr_latch is set, put the appropriate bus contents into MDR
  159.    if(MDR_LATCH) {
  160.       switch (MDR_SEL) {
  161.          case A_BUS:
  162.             mdr = a_bus;
  163.             break;
  164.          case B_BUS:
  165.             mdr = b_bus;
  166.             break;
  167.          case ALU_BUS:
  168.             mdr = alu_bus;
  169.             break;
  170.          default:    // mdr_latch was set but mdr_sel wasn't called
  171.             return("Simulator Logic Error: No mdr_sel");
  172.       }
  173.    }
  174.  
  175.    // Memory read 
  176.    if(MAR_OUT_EN && !MDR_OUT_EN)
  177.    {
  178.       // read the data onto the DATA_BUS
  179.       if(!Peek(mar, data_bus))
  180.         return("Bus Error");
  181.  
  182.       // bump the read cycle counter
  183.       number_of_reads++;
  184.    }
  185.  
  186.    // Memory write
  187.    if(MAR_OUT_EN && MDR_OUT_EN) {
  188.       // write the contents of MDR to the location pointed to by MAR
  189.       if(!Poke(mar, mdr))
  190.         return("Bus Error");
  191.  
  192.       // bump the write cycle counter
  193.       number_of_writes++;
  194.    }
  195.  
  196.    // If ir_latch is set, load the DATA_BUS into the IR
  197.    if(IR_LATCH)
  198.       ir = data_bus;
  199.  
  200.    // Make sure there isn't write bus contention
  201.    if(DB_GT && ALU_GT)
  202.       return("Simulator Logic Error: WRT_BUS Contention");
  203.  
  204.    // Set the WRT_BUS if a signal is gated thru to it
  205.    if(DB_GT)
  206.       wrt_bus = data_bus;
  207.    else if(ALU_GT)
  208.       wrt_bus = alu_bus;
  209.  
  210.    // Write the source and/or destination regs if specified
  211.    if(WRT_A)
  212.       register_set.SetRegister(A_SEL, wrt_bus);
  213.    if(WRT_B)
  214.       register_set.SetRegister(B_SEL, wrt_bus);
  215.  
  216.    // Bump the cycle counter
  217.    number_of_cycles++;
  218.  
  219.    // Reset the signals
  220.    ResetSignals();
  221.  
  222.    // No Error! So return NULL pointer...
  223.    return((void*)0);
  224. }
  225.  
  226.